<template>
  <div class="app-container">
    <!-- 页面头部 -->
    <PageHeader back-text="返回项目列表" back-type="back" :title="projectInfo.proName || '加载中...'" />

    <!-- 项目详情卡片 -->
    <ProjectDetail :project-info="projectInfo" :loading="projectLoading" />

    <!-- 周日志信息卡片 -->
    <el-card class="box-card weeklog-card" v-loading="loading">
      <!-- 周日志信息操作按钮 -->
      <div class="card-header mb-4">
        <div class="card-header-left">
          <span class="title">周总结填报</span>
          <div class="week-info">
            <span class="week-label">第{{ weeklogData?.weekOrder || 1 }}周</span>
          </div>
        </div>
        <div class="flex items-center" style="gap: 6px">
          <el-button circle @click="handleQuery" :title="'刷新'" class="refresh-button">
            <el-icon>
              <Refresh />
            </el-icon>
          </el-button>
          <ProjectStatusDisplay label="周总结审核状态" :status-options="approval_commit_status"
            :status-value="weeklogData?.auditStatus" />
        </div>
      </div>



      <!-- 周日志记录表格 -->
      <div class="weeklog-container">
        <el-table :data="recordList" border style="width: 100%" row-key="id" :row-class-name="tableRowClassName"
          :max-height="600" class="weeklog-table">
          <!-- 序号 -->
          <el-table-column label="序号" align="center" width="80" fixed="left">
            <template #default="scope">
              <span>{{ scope.$index + 1 }}</span>
            </template>
          </el-table-column>
          <!-- 回款节点 -->
          <el-table-column label="回款节点" width="200" align="center" fixed="left" show-overflow-tooltip>
            <template #default="scope">
              <span class="receive-name">{{ scope.row.receiveName || '-' }}</span>
            </template>
          </el-table-column>
          <!-- 技术流程 -->
          <el-table-column label="技术流程" width="200" fixed="left" align="center" show-overflow-tooltip>
            <template #default="scope">
              <span class="tech-flow-display">{{ scope.row.techFlow || '-' }}</span>
            </template>
          </el-table-column>

          <!-- 详细工作计划 -->
          <el-table-column label="详细工作计划" align="left" width="300" show-overflow-tooltip>
            <template #default="scope">
              <el-tooltip :content="scope.row.detailWorkPlan" placement="top" :disabled="!scope.row.detailWorkPlan">
                <span class="text-overflow">{{ scope.row.detailWorkPlan || '-' }}</span>
              </el-tooltip>
            </template>
          </el-table-column>

          <!-- 计划开始时间 -->
          <el-table-column label="计划开始时间" align="center" width="120">
            <template #default="scope">
              {{ scope.row.planStartTime ? parseTime(scope.row.planStartTime, '{y}-{m}-{d}') : '-' }}
            </template>
          </el-table-column>

          <!-- 计划结束时间 -->
          <el-table-column label="计划结束时间" align="center" width="120">
            <template #default="scope">
              {{ scope.row.planEndTime ? parseTime(scope.row.planEndTime, '{y}-{m}-{d}') : '-' }}
            </template>
          </el-table-column>

          <!-- 本周工作计划 -->
          <el-table-column label="本周工作计划" align="left" width="300" show-overflow-tooltip>
            <template #default="scope">
              <span class="text-overflow">{{ scope.row.thisWeekPlan || '-' }}</span>
            </template>
          </el-table-column>

          <!-- 本周完成情况 -->
          <el-table-column label="本周完成情况" align="left" width="300">
            <template #default="scope">
              <el-input v-if="scope.row.isEditing" v-model="scope.row.thisWeekCase" type="textarea"
                placeholder="请描述本周的完成情况" :rows="3" />
              <el-tooltip v-else :content="scope.row.thisWeekCase" placement="top" :disabled="!scope.row.thisWeekCase">
                <span class="text-overflow">{{ scope.row.thisWeekCase || '-' }}</span>
              </el-tooltip>
            </template>
          </el-table-column>

          <!-- 节点完成百分比 -->
          <el-table-column label="该项工作内容累计完成百分比" align="center" width="180">
            <template #default="scope">
              <PercentageInput v-if="scope.row.isEditing" v-model="scope.row.nodeCompleteRate"
                placeholder="请输入完成百分比（0-100）" :required="true" :min="0" :max="100" :precision="2" />
              <span v-else-if="scope.row.nodeCompleteRate !== null && scope.row.nodeCompleteRate !== undefined">
                {{ formatPercentage(Number(scope.row.nodeCompleteRate), 2) }}
              </span>
              <span v-else>-</span>
            </template>
          </el-table-column>

          <!-- 下周计划 -->
          <el-table-column label="下周工作计划" align="left" width="300">
            <template #default="scope">
              <el-input v-if="scope.row.isEditing" v-model="scope.row.nextWeekPlan" type="textarea"
                placeholder="请描述下周的工作计划" :rows="3" />
              <el-tooltip v-else :content="scope.row.nextWeekPlan" placement="top" :disabled="!scope.row.nextWeekPlan">
                <span class="text-overflow">{{ scope.row.nextWeekPlan || '-' }}</span>
              </el-tooltip>
            </template>
          </el-table-column>

          <!-- 备注 -->
          <el-table-column label="备注" align="left" width="300">
            <template #default="scope">
              <el-input v-if="scope.row.isEditing" v-model="scope.row.remark" :rows="3" type="textarea"
                placeholder="请输入备注信息" />
              <el-tooltip v-else :content="scope.row.remark" placement="top" :disabled="!scope.row.remark">
                <span class="text-overflow">{{ scope.row.remark || '-' }}</span>
              </el-tooltip>
            </template>
          </el-table-column>

          <!-- 记录人 -->
          <el-table-column label="记录人" align="center" width="120">
            <template #default="scope">
              <span>{{ scope.row.recordName || '-' }}</span>
            </template>
          </el-table-column>

          <!-- 记录时间 -->
          <el-table-column label="记录时间" align="center" prop="recordTime" width="120">
            <template #default="scope">
              {{ scope.row.recordTime ? parseTime(scope.row.recordTime, '{y}-{m}-{d}') : '' }}
            </template>
          </el-table-column>

          <!-- 逾期状态 -->
          <el-table-column label="逾期状态" align="center" width="100" fixed="right">
            <template #default="scope">
              <el-tag :type="getOverdueStatusType(isOverdue(scope.row.planEndTime))" size="small">
                {{ getOverdueStatusText(isOverdue(scope.row.planEndTime)) }}
              </el-tag>
            </template>
          </el-table-column>

          <!-- 操作 -->
          <el-table-column label="操作" width="180" fixed="right" align="center">
            <template #default="scope">
              <!-- 编辑模式下的操作按钮 -->
              <template v-if="scope.row.isEditing">
                <el-button size="small" type="primary" @click="saveRecord(scope.row)" :loading="scope.row.saving"> 保存
                </el-button>
                <el-button size="small" type="danger" @click="cancelEdit(scope.row)" :disabled="scope.row.saving"> 取消
                </el-button>
              </template>
              <!-- 查看模式下的操作按钮 -->
              <template v-else>
                <el-tooltip content="修改" placement="top">
                  <el-button link type="primary" icon="Edit" @click="editRecord(scope.row)"
                    v-hasPermi="['project:weeklog:edit']"></el-button>
                </el-tooltip>
                <el-tooltip content="查看节点编辑记录" placement="top">
                  <el-button link type="info" icon="TrendCharts" @click="viewRecordStatistic(scope.row)"
                    v-hasPermi="['project:weeklog:query']"></el-button>
                </el-tooltip>
              </template>
            </template>
          </el-table-column>

          <template #empty>
            <el-empty description="暂无周日志数据" />
          </template>
        </el-table>

        <!-- 底部滑动提示 + 右侧批量保存按钮（同一行） -->
        <div class="scroll-tip-container">
          <div class="scroll-tip">
            <el-icon class="tip-icon">
              <ArrowLeft />
            </el-icon>
            <span class="tip-text">左右滑动查看更多信息</span>
            <el-icon class="tip-icon">
              <ArrowRight />
            </el-icon>
          </div>
          <div class="batch-save-right" v-if="hasEditingRecords">
            <el-button type="success" @click="handleBatchSave" class="batch-save-btn">
              <el-icon class="mr-1">
                <Check />
              </el-icon>
              批量保存
            </el-button>
          </div>
        </div>


      </div>
    </el-card>

    <!-- 底部：项目整体进度（常驻显示） -->
    <el-card class="box-card weeklog-card" v-loading="loading">
      <template #header>
        <div class="card-header">
          <div class="card-header-left">
            <span class="title">项目整体进度</span>
            <el-tag type="primary" size="small" class="cycle-tag">第 {{ weeklogData?.weekOrder || 1 }} 周</el-tag>
          </div>
          <div class="card-header-actions">
            <el-button circle size="small" class="collapse-btn" @click="statisticsCollapsed = !statisticsCollapsed">
              <el-icon :class="{ rotated: !statisticsCollapsed }">
                <ArrowDown />
              </el-icon>
            </el-button>
          </div>
        </div>
      </template>

      <transition name="stat-collapse">
        <div v-show="!statisticsCollapsed">
          <!-- 整体统计布局 -->
          <div class="statistics-layout">
            <!-- 项目完成度统计模块 -->
            <div class="progress-module">
              <div class="section-header">
                <el-icon class="section-icon">
                  <TrendCharts />
                </el-icon>
                <span class="section-title">项目完成度</span>
              </div>
              <div class="module-content">
                <div class="chart-container">
                  <div id="progressChartBottom" class="progress-chart"></div>
                  <div class="chart-center-text">
                    <div class="percent-text">
                      {{
                        weeklogData?.totalProgress !== null && weeklogData?.totalProgress !== undefined
                          ? (Number(weeklogData.totalProgress) * 100).toFixed(1) + '%'
                          : '0.0%'
                      }}
                    </div>
                    <div class="chart-label">完成度</div>
                  </div>
                </div>
                <div class="info-panel">
                  <div class="status-badge">
                    <el-tag :type="getProgressStatusType()" size="large">{{ getProgressStatusText() }}</el-tag>
                  </div>
                  <div class="time-info">
                    <div class="time-item">
                      <div class="time-label">
                        <el-icon>
                          <Clock />
                        </el-icon>
                        计划开始时间
                      </div>
                      <div class="time-value">
                        {{ weeklogData?.proStartTime ? parseTime(weeklogData.proStartTime, '{y}-{m}-{d}') : '-' }}
                      </div>
                    </div>
                    <div class="time-item">
                      <div class="time-label">
                        <el-icon>
                          <Clock />
                        </el-icon>
                        计划结束时间
                      </div>
                      <div class="time-value">
                        {{ weeklogData?.proEndTime ? parseTime(weeklogData.proEndTime, '{y}-{m}-{d}') : '-' }}
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- 工时统计模块 -->
            <div class="worktime-module">
              <div class="section-header">
                <el-icon class="section-icon">
                  <Timer />
                </el-icon>
                <span class="section-title">工时统计</span>
              </div>
              <div class="module-content">
                <div class="chart-container">
                  <div id="worktimeChartBottom" class="worktime-chart"></div>
                  <div class="chart-center-text">
                    <div class="percent-text">
                      {{ weeklogData?.workTimeConsumeRate ? (Number(weeklogData.workTimeConsumeRate) * 100).toFixed(1) +
                        '%'
                        : '0.0%' }}
                    </div>
                    <div class="chart-label">耗时比例</div>
                  </div>
                </div>
                <div class="info-panel">
                  <div class="worktime-stats">
                    <div class="worktime-item">
                      <div class="worktime-icon plan">
                        <el-icon>
                          <Timer />
                        </el-icon>
                      </div>
                      <div class="worktime-details">
                        <div class="worktime-label">计划总工时</div>
                        <div class="worktime-value">
                          {{ weeklogData?.planTotalWorkTime ? Number(weeklogData.planTotalWorkTime).toFixed(1) : '0.0'
                          }}h
                        </div>
                      </div>
                    </div>
                    <div class="worktime-item">
                      <div class="worktime-icon actual">
                        <el-icon>
                          <AlarmClock />
                        </el-icon>
                      </div>
                      <div class="worktime-details">
                        <div class="worktime-label">实际耗时</div>
                        <div class="worktime-value">
                          {{ weeklogData?.proTotalConsumeTime ? Number(weeklogData.proTotalConsumeTime).toFixed(1) :
                            '0.0'
                          }}h
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="efficiency-badge">
                    <el-tag :type="getWorkTimeConsumeRateType()" size="large">
                      效率：{{ weeklogData?.workTimeConsumeRate ? (Number(weeklogData.workTimeConsumeRate) *
                        100).toFixed(1) +
                        '%' : '0.0%' }}
                    </el-tag>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </transition>
    </el-card>



    <!-- 节点编辑记录统计弹窗 -->
    <el-dialog v-model="statisticDialogVisible" :title="`${currentStatisticNode?.workContent || '工作内容'} - 周总结记录统计`"
      width="90%" destroy-on-close class="statistic-dialog" @close="handleStatisticDialogClose">
      <div v-loading="statisticLoading" class="statistic-container">
        <!-- 统计图表区域 -->
        <el-card class="chart-card mb-4" v-if="statisticList.length > 0">
          <template #header>
            <div class="chart-header">
              <el-icon class="chart-icon">
                <TrendCharts />
              </el-icon>
              <span>节点完成率变化趋势</span>
            </div>
          </template>
          <div id="nodeCompletionChart" style="width: 100%; height: 300px; min-height: 300px"></div>
        </el-card>

        <!-- 记录列表 -->
        <el-card>
          <template #header>
            <div class="record-header">
              <el-icon class="record-icon">
                <List />
              </el-icon>
              <span>周总结记录详情</span>
            </div>
          </template>

          <el-table :data="statisticList" border style="width: 100%" v-if="statisticList.length > 0">
            <el-table-column label="周数" prop="weekOrder" width="80" align="center">
              <template #default="scope">
                <el-tag type="primary">第{{ scope.row.weekOrder }}周</el-tag>
              </template>
            </el-table-column>

            <el-table-column label="回款节点" width="200" align="center" show-overflow-tooltip>
              <template #default="scope">
                <span class="receive-name">{{ scope.row.receiveName || '-' }}</span>
              </template>
            </el-table-column>

            <el-table-column label="技术流程" width="200" align="center" show-overflow-tooltip>
              <template #default="scope">
                <span class="tech-flow-display">{{ scope.row.techFlow || '-' }}</span>
              </template>
            </el-table-column>


            <el-table-column label="本周工作计划" align="left" width="300" show-overflow-tooltip>
              <template #default="scope">
                <span class="text-overflow">{{ scope.row.thisWeekPlan || '-' }}</span>
              </template>
            </el-table-column>

            <el-table-column label="本周完成情况" prop="thisWeekCase" width="300" align="left">
              <template #default="scope">
                <el-tooltip :content="scope.row.thisWeekCase" placement="top" :disabled="!scope.row.thisWeekCase">
                  <span class="text-overflow">{{ scope.row.thisWeekCase || '-' }}</span>
                </el-tooltip>
              </template>
            </el-table-column>

            <el-table-column label="工作内容完成百分比" align="center" width="180">
              <template #header>
                <el-tooltip content="该项工作内容累计完成百分比" placement="top">
                  <span>工作内容完成百分比</span>
                </el-tooltip>
              </template>
              <template #default="scope">
                <el-tag :type="getCompleteRateType(scope.row.nodeCompleteRate)">
                  {{ scope.row.nodeCompleteRate ? Number(scope.row.nodeCompleteRate).toFixed(2) + '%' : '0.00%'
                  }}
                </el-tag>
              </template>
            </el-table-column>

            <el-table-column label="下周工作计划" align="left" width="300">
              <template #default="scope">
                <el-tooltip :content="scope.row.nextWeekPlan" placement="top" :disabled="!scope.row.nextWeekPlan">
                  <span class="text-overflow">{{ scope.row.nextWeekPlan || '-' }}</span>
                </el-tooltip>
              </template>
            </el-table-column>

            <el-table-column label="备注" prop="remark" width="300" align="left">
              <template #default="scope">
                <el-tooltip :content="scope.row.remark" placement="top" :disabled="!scope.row.remark">
                  <span class="text-overflow">{{ scope.row.remark || '-' }}</span>
                </el-tooltip>
              </template>
            </el-table-column>

            <el-table-column label="记录人" prop="recordName" width="120" align="center">
              <template #default="scope">
                <span>{{ scope.row.recordName || '-' }}</span>
              </template>
            </el-table-column>

            <el-table-column label="记录时间" prop="recordTime" width="120" align="center">
              <template #default="scope">
                {{ scope.row.recordTime ? parseTime(scope.row.recordTime, '{y}-{m}-{d}') : '-' }}
              </template>
            </el-table-column>
          </el-table>

          <el-empty v-else description="暂无编辑记录" />
        </el-card>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="statisticDialogVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 审核流程组件 -->
    <ApprovalFlow v-model:visible="approvalFlowVisible" :business-type="businessType"
      :business-id="currentWeeklogForApproval?.id" :flag="true" :pro-id="route.params.proId as string"  :title="`周总结审核-${projectInfo.proName || ''}`"
      @confirm="handleApprovalConfirm" @cancel="handleApprovalCancel" />

    <!-- 右下角固定提交审核按钮 -->
    <div class="fixed-submit-button">
      <el-button type="primary" @click="handleSubmitWeeklog" v-hasPermi="['project:weeklog:audit']" size="large"
        class="submit-audit-btn" :loading="false">
        <el-icon>
          <Upload />
        </el-icon>
        <span>提交周总结审核</span>
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { getProDetail } from '@/api/project/init/proInfo';
import type { ProInfoVO } from '@/api/project/init/proInfo/types';
import { getWeeklogByProId, initWeeklog, updateWeeklogRecord, getWeeklogRecordStatistic, batchUpdateWeeklogRecord } from '@/api/project/log/weeklog';
import type { ProWeeklogRecordForm, ProWeeklogVO, ProWeeklogRecordVO } from '@/api/project/log/weeklog/types';
import ProjectDetail from '@/views/project/components/ProjectDetail.vue';
import PageHeader from '@/views/project/components/PageHeader/index.vue';
import { isOverdue, getOverdueStatusText, getOverdueStatusType } from '@/utils/dateUtils';
import ProjectStatusDisplay from '@/views/project/components/ProjectStatusDisplay.vue';
import { PercentageInput, formatPercentage } from '@/components/NumberInput';
import ApprovalFlow from '@/components/ApprovalFlow/index.vue';
import * as echarts from 'echarts';

const route = useRoute();
const router = useRouter();

// 项目信息
const projectInfo = ref<Partial<ProInfoVO>>({});
const projectLoading = ref(false);

const { proxy } = getCurrentInstance() as any;
const { approval_commit_status } = toRefs<any>(proxy?.useDict('approval_commit_status'));

// 周日志数据
const weeklogData = ref<ProWeeklogVO | null>(null);
const recordList = ref<
  (ProWeeklogRecordVO & { isEditing?: boolean; saving?: boolean; originalData?: any })[]
>([]);



// 加载状态
const loading = ref(false);

// 统计弹窗相关状态
const statisticDialogVisible = ref(false);
const statisticList = ref<ProWeeklogRecordVO[]>([]);
const statisticLoading = ref(false);
const currentStatisticNode = ref<ProWeeklogRecordVO | null>(null);
const chartInstance = ref<any>(null);
const chartResizeHandler = ref<any>(null);



// 底部进度图实例
const progressChartBottomInstance = ref<any>(null);
const progressChartBottomResizeHandler = ref<any>(null);

// 工时统计图实例
const worktimeChartBottomInstance = ref<any>(null);
const worktimeChartBottomResizeHandler = ref<any>(null);

// 整体统计板块折叠
const statisticsCollapsed = ref(false);

// 审核流程相关
const approvalFlowVisible = ref(false);
const currentWeeklogForApproval = ref<any>(null);
const businessType = ref('WEEK-LOG-AUDIT');

// 防抖函数
const debounce = (func: Function, wait: number) => {
  let timeout: NodeJS.Timeout;
  return function executedFunction(...args: any[]) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

// 检查是否有正在编辑的记录
const hasEditingRecords = computed(() => {
  return recordList.value.some((record) => record.isEditing);
});

/**
 * 刷新数据
 */
const handleQuery = () => {
  // 检查是否有未保存的编辑内容
  if (hasEditingRecords.value) {
    ElMessageBox.confirm(
      '您有未保存的编辑内容，刷新后所有编辑状态将丢失。建议先批量保存或单独保存当前编辑内容。是否继续刷新？',
      '确认刷新',
      {
        confirmButtonText: '继续刷新',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      initAndGetWeeklogData(false);
    }).catch(() => {
      // 用户取消刷新
    });
  } else {
    initAndGetWeeklogData(false);
  }
};

/**
 * 保存未保存的编辑中的记录（排除正在保存saving中的行）
 * 注意：刷新操作不会保留编辑状态
 */
const saveUnsavedEditingRecords = () => {
  // 刷新操作不保留编辑状态，返回空数组
  return [];
};

/**
 * 恢复未保存的编辑中的记录（跳过正在保存的行）
 * 注意：刷新操作不会保留编辑状态
 */
const restoreUnsavedEditingRecords = (unsaved: any[]) => {
  // 刷新操作不保留编辑状态，不执行任何操作
  return;
};

/**
 * 初始化周日志
 */
const initWeeklogData = async () => {
  const proId = route.params.proId as string;
  if (!proId) {
    ElMessage.error('项目ID不能为空');
    return;
  }

  try {
    await initWeeklog(Number(proId), false);
  } catch (error) {
    console.error('初始化周日志失败:', error);
    ElMessage.error('初始化周日志失败');
  }
};

/**
 * 获取周日志数据
 */
const getWeeklogData = async () => {
  const proId = route.params.proId as string;
  if (!proId) {
    ElMessage.error('项目ID不能为空');
    return;
  }

  try {
    // 保存当前未保存的编辑项
    const unsaved = saveUnsavedEditingRecords();

    loading.value = true;
    const res = await getWeeklogByProId(Number(proId));
    weeklogData.value = res.data;

    recordList.value = (res.data?.recordList || []).map((item: ProWeeklogRecordVO) => ({
      ...item,
      isEditing: false,
      saving: false,
      originalData: null
    }));

    // 恢复未保存的编辑项
    restoreUnsavedEditingRecords(unsaved);

    // 刷新底部图表
    nextTick(() => {
      setTimeout(() => {
        renderProgressChartBottom();
        renderWorktimeChartBottom();
      }, 100);
    });

  } catch (error) {
    console.error('获取周日志数据失败:', error);
  } finally {
    loading.value = false;
  }
};

/**
 * 初始化并获取周日志数据
 */
const initAndGetWeeklogData = async (flag:boolean) => {
  const proId = route.params.proId as string;
  if (!proId) {
    ElMessage.error('项目ID不能为空');
    return;
  }

  try {
    loading.value = true;

    // 先初始化周日志
    await initWeeklog(Number(proId), flag);

    // 再获取周日志数据
    await getWeeklogData();

  } catch (error) {
  } finally {
    loading.value = false;
  }
};

/**
 * 获取项目信息
 */
const getProjectDetail = async () => {
  const proId = route.params.proId as string;
  if (!proId) {
    ElMessage.error('项目ID不能为空');
    return;
  }

  try {
    projectLoading.value = true;
    const res = await getProDetail(proId);
    projectInfo.value = res.data || {};
  } catch (error) {
    console.error('获取项目信息失败:', error);
  } finally {
    projectLoading.value = false;
  }
};

/**
 * 编辑记录
 */
const editRecord = (row: ProWeeklogRecordVO & { isEditing?: boolean; saving?: boolean; originalData?: any }) => {
  try {
    // 保存原始数据用于取消时恢复
    row.originalData = JSON.parse(JSON.stringify(row));

    row.isEditing = true;
    row.saving = false;
  } catch (error) {
    console.error('编辑记录失败:', error);
  }
};

/**
 * 校验记录数据
 */
const validateRecord = (row: ProWeeklogRecordVO): { valid: boolean; errors: string[] } => {
  const errors: string[] = [];

  // 节点完成百分比校验
  if (row.nodeCompleteRate !== null && row.nodeCompleteRate !== undefined) {
    const rateValue = Number(row.nodeCompleteRate);
    if (isNaN(rateValue) || rateValue < 0 || rateValue > 100) {
      errors.push('节点完成百分比必须在0-100之间');
    }
  }

  return {
    valid: errors.length === 0,
    errors
  };
};

/**
 * 保存记录
 */
const saveRecord = async (
  row: ProWeeklogRecordVO & { isEditing?: boolean; saving?: boolean; originalData?: any }
) => {
  // 先进行数据校验
  const validation = validateRecord(row);
  if (!validation.valid) {
    ElMessage.error(`保存失败：${validation.errors.join('；')}`);
    return;
  }

  row.saving = true;
  try {
    // 封装记录数据 - 前端发送原始的百分比值（0-100），后端负责除以100
    // 包含冗余字段更新所需的ID信息
    const recordData: ProWeeklogRecordForm = {
      id: row.id,
      proId: row.proId,
      receiveId: row.receiveId,
      planId: row.planId,
      weeklogId: row.weeklogId,
      version: row.version,
      thisWeekCase: row.thisWeekCase,
      nodeCompleteRate: row.nodeCompleteRate,
      nextWeekPlan: row.nextWeekPlan,
      remark: row.remark,
      weekOrder: row.weekOrder
    };

    // 调用后端接口保存
    await updateWeeklogRecord(recordData);

    ElMessage.success('保存成功');
    row.isEditing = false;
    row.originalData = null;

    // 重新获取数据（当前保存行不会恢复为编辑态，其他未保存的编辑态将被恢复）
    getWeeklogData();
  } catch (error) {
    console.error('保存周日志记录失败:', error);
    ElMessage.error('保存失败');
  } finally {
    row.saving = false;
  }
};

/**
 * 取消编辑
 */
const cancelEdit = (
  row: ProWeeklogRecordVO & { isEditing?: boolean; saving?: boolean; originalData?: any }
) => {
  if (row.originalData) {
    // 恢复原始数据
    Object.assign(row, row.originalData);
    row.isEditing = false;
    row.originalData = null;
  }
};



/**
 * 表格行样式
 */
const tableRowClassName = ({ row }: { row: ProWeeklogRecordVO & { isEditing?: boolean } }) =>
  row.isEditing ? 'editing-row' : '';

/**
 * 查看节点编辑记录
 */
const viewRecordStatistic = async (
  row: ProWeeklogRecordVO & { isEditing?: boolean; saving?: boolean; originalData?: any }
) => {
  if (!row.id) {
    ElMessage.error('记录ID不能为空');
    return;
  }

  currentStatisticNode.value = row;
  statisticDialogVisible.value = true;

  try {
    statisticLoading.value = true;
    const res = await getWeeklogRecordStatistic(row.id);
    statisticList.value = res.data || [];

    // 绘制图表
    if (statisticList.value.length > 0) {
      nextTick(() => {
        // 额外延时确保DOM完全渲染
        setTimeout(() => {
          renderNodeCompletionChart();
        }, 100);
      });
    }
  } catch (error) {
    console.error('获取节点编辑记录失败:', error);
    ElMessage.error('获取节点编辑记录失败');
  } finally {
    statisticLoading.value = false;
  }
};

/**
 * 处理统计弹窗关闭
 */
const handleStatisticDialogClose = () => {
  // 清理resize事件监听器
  if (chartResizeHandler.value) {
    window.removeEventListener('resize', chartResizeHandler.value);
    chartResizeHandler.value = null;
  }

  // 清理图表实例
  if (chartInstance.value) {
    chartInstance.value.dispose();
    chartInstance.value = null;
  }

  // 清理数据
  statisticList.value = [];
  currentStatisticNode.value = null;
};

/**
 * 获取完成率标签类型
 */
const getCompleteRateType = (rate: number | null | undefined) => {
  if (!rate) return 'info';
  const rateNum = Number(rate);
  if (rateNum >= 100) return 'success';
  if (rateNum >= 80) return 'success';
  if (rateNum >= 50) return 'warning';
  return 'danger';
};

/**
 * 获取进度状态类型
 */
const getProgressStatusType = () => {
  const progress = weeklogData.value?.totalProgress ? Number(weeklogData.value.totalProgress) * 100 : 0;
  if (progress >= 100) return 'success';
  if (progress >= 80) return 'success';
  if (progress >= 50) return 'warning';
  if (progress >= 20) return 'info';
  return 'danger';
};

/**
 * 获取进度状态文本
 */
const getProgressStatusText = () => {
  const progress = weeklogData.value?.totalProgress ? Number(weeklogData.value.totalProgress) * 100 : 0;
  if (progress >= 100) return '已完成';
  if (progress >= 80) return '接近完成';
  if (progress >= 50) return '进展良好';
  if (progress >= 20) return '进行中';
  return '刚开始';
};

/**
 * 获取进度条颜色
 */
const getProgressColor = () => {
  const progress = weeklogData.value?.totalProgress ? Number(weeklogData.value.totalProgress) * 100 : 0;
  if (progress >= 100) return '#67C23A';
  if (progress >= 80) return '#95D475';
  if (progress >= 50) return '#E6A23C';
  if (progress >= 20) return '#F56C6C';
  return '#909399';
};

/**
 * 获取工时消耗百分比标签类型
 */
const getWorkTimeConsumeRateType = () => {
  const consumeRate = weeklogData.value?.workTimeConsumeRate ? Number(weeklogData.value.workTimeConsumeRate) * 100 : 0;
  if (consumeRate <= 80) return 'success'; // 消耗率低于80%，效率良好
  if (consumeRate <= 100) return 'warning'; // 消耗率80%-100%，正常范围
  return 'danger'; // 消耗率超过100%，超时
};

/**
 * 安全转换数值
 */
const safeNumber = (value: any): number => Number(value) || 0;

// 不再需要侧边面板开关



/**
 * 渲染底部的项目整体进度环形图
 */
const renderProgressChartBottom = () => {
  try {
    const chartDom = document.getElementById('progressChartBottom');
    if (!chartDom) {
      return;
    }

    // 销毁之前的图表实例
    if (progressChartBottomInstance.value) {
      progressChartBottomInstance.value.dispose();
      progressChartBottomInstance.value = null;
    }

    const myChart = echarts.init(chartDom);
    progressChartBottomInstance.value = myChart;

    const progress = weeklogData.value?.totalProgress ? Number(weeklogData.value.totalProgress) * 100 : 0;

    const option = {
      series: [
        {
          name: '项目进度',
          type: 'pie',
          radius: ['60%', '90%'],
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 6,
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: false
          },
          emphasis: {
            label: {
              show: false
            }
          },
          labelLine: {
            show: false
          },
          data: [
            {
              value: progress,
              name: '已完成',
              itemStyle: {
                color: {
                  type: 'linear',
                  x: 0,
                  y: 0,
                  x2: 1,
                  y2: 1,
                  colorStops:
                    progress >= 80
                      ? [
                        { offset: 0, color: '#67C23A' },
                        { offset: 1, color: '#95D475' }
                      ]
                      : progress >= 50
                        ? [
                          { offset: 0, color: '#E6A23C' },
                          { offset: 1, color: '#F7BA2A' }
                        ]
                        : [
                          { offset: 0, color: '#F56C6C' },
                          { offset: 1, color: '#F78989' }
                        ]
                }
              }
            },
            {
              value: 100 - progress,
              name: '未完成',
              itemStyle: {
                color: '#F5F7FA'
              }
            }
          ]
        }
      ]
    };

    myChart.setOption(option);

    // 响应式处理
    const debouncedResize = debounce(() => {
      if (myChart && !myChart.isDisposed()) {
        myChart.resize();
      }
    }, 200);

    progressChartBottomResizeHandler.value = debouncedResize;
    window.addEventListener('resize', debouncedResize);
  } catch (error) {
    console.error('渲染底部进度图表失败:', error);
  }
};

/**
 * 渲染工时统计环形图
 */
const renderWorktimeChartBottom = () => {
  try {
    const chartDom = document.getElementById('worktimeChartBottom');
    if (!chartDom) {
      return;
    }

    // 销毁之前的图表实例
    if (worktimeChartBottomInstance.value) {
      worktimeChartBottomInstance.value.dispose();
      worktimeChartBottomInstance.value = null;
    }

    const myChart = echarts.init(chartDom);
    worktimeChartBottomInstance.value = myChart;

    const planTotalWorkTime = weeklogData.value?.planTotalWorkTime ? Number(weeklogData.value.planTotalWorkTime) : 0;
    const proTotalConsumeTime = weeklogData.value?.proTotalConsumeTime ? Number(weeklogData.value.proTotalConsumeTime) : 0;
    const consumeRate = weeklogData.value?.workTimeConsumeRate ? Number(weeklogData.value.workTimeConsumeRate) * 100 : 0;

    const option = {
      series: [
        {
          name: '工时统计',
          type: 'pie',
          radius: ['60%', '90%'],
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 6,
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: false
          },
          emphasis: {
            label: {
              show: false
            }
          },
          labelLine: {
            show: false
          },
          data: [
            {
              value: proTotalConsumeTime,
              name: '已消耗',
              itemStyle: {
                color: {
                  type: 'linear',
                  x: 0,
                  y: 0,
                  x2: 1,
                  y2: 1,
                  colorStops:
                    consumeRate <= 80
                      ? [
                        { offset: 0, color: '#67C23A' },
                        { offset: 1, color: '#95D475' }
                      ]
                      : consumeRate <= 100
                        ? [
                          { offset: 0, color: '#E6A23C' },
                          { offset: 1, color: '#F7BA2A' }
                        ]
                        : [
                          { offset: 0, color: '#F56C6C' },
                          { offset: 1, color: '#F78989' }
                        ]
                }
              }
            },
            {
              value: Math.max(0, planTotalWorkTime - proTotalConsumeTime),
              name: '剩余工时',
              itemStyle: {
                color: '#F5F7FA'
              }
            }
          ]
        }
      ]
    };

    myChart.setOption(option);

    // 响应式处理
    const debouncedResize = debounce(() => {
      if (myChart && !myChart.isDisposed()) {
        myChart.resize();
      }
    }, 200);

    worktimeChartBottomResizeHandler.value = debouncedResize;
    window.addEventListener('resize', debouncedResize);
  } catch (error) {
    console.error('渲染工时统计图表失败:', error);
  }
};

/**
 * 渲染节点完成率趋势图表
 */
const renderNodeCompletionChart = () => {
  try {
    const chartDom = document.getElementById('nodeCompletionChart');
    if (!chartDom) {
      console.warn('图表容器不存在');
      return;
    }

    // 处理数据
    if (!statisticList.value || statisticList.value.length === 0) {
      chartDom.innerHTML = `
        <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; color: #909399;">
          <el-icon style="font-size: 48px; margin-bottom: 16px; opacity: 0.5;">
            <DataAnalysis />
          </el-icon>
          <div style="font-size: 14px; margin-bottom: 8px;">暂无数据</div>
          <div style="font-size: 12px; opacity: 0.7;">该工作内容暂无历史记录</div>
        </div>
      `;
      return;
    }

    // 清空容器内容，准备渲染图表
    chartDom.innerHTML = '';

    // 销毁之前的图表实例
    if (chartInstance.value) {
      chartInstance.value.dispose();
      chartInstance.value = null;
    }

    const myChart = echarts.init(chartDom);
    chartInstance.value = myChart;

    // 处理图表数据
    const chartData = statisticList.value.map((item) => ({
      week: `第${item.weekOrder}周`,
      rate: Number(safeNumber(item.nodeCompleteRate).toFixed(2)),
      weekOrder: item.weekOrder
    }));

    const weekData = chartData.map((item) => item.week);
    const rateData = chartData.map((item) => item.rate);

    const option = {
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(255, 255, 255, 0.95)',
        borderColor: '#e4e7ed',
        borderWidth: 1,
        textStyle: {
          color: '#606266'
        },
        formatter: function (params) {
          let html = `<div style="margin-bottom: 6px; font-weight: bold;">${params[0].axisValue}</div>`;
          params.forEach((param) => {
            html += `<div style="margin: 2px 0;">
              <span style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: ${param.color}; margin-right: 8px;"></span>
              节点完成率: <span style="font-weight: bold;">${param.value}%</span>
            </div>`;
          });
          return html;
        }
      },
      grid: {
        left: '3%',
        right: '8%',
        bottom: '3%',
        top: '15%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: weekData,
        boundaryGap: false,
        axisLabel: {
          color: '#909399',
          fontSize: 12,
          rotate: weekData.length > 6 ? 45 : 0
        },
        axisLine: {
          lineStyle: {
            color: '#e4e7ed'
          }
        }
      },
      yAxis: {
        type: 'value',
        name: '完成率(%)',
        min: 0,
        max: 100,
        axisLabel: {
          formatter: '{value}%',
          color: '#909399'
        },
        axisLine: {
          lineStyle: {
            color: '#e4e7ed'
          }
        },
        splitLine: {
          lineStyle: {
            color: '#f5f7fa'
          }
        }
      },
      series: [
        {
          name: '节点完成率',
          type: 'line',
          data: rateData,
          smooth: true,
          symbolSize: 8,
          lineStyle: {
            color: '#409EFF',
            width: 3
          },
          itemStyle: {
            color: '#409EFF',
            borderColor: '#fff',
            borderWidth: 2
          },
          areaStyle: {
            color: {
              type: 'linear',
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                {
                  offset: 0,
                  color: 'rgba(64, 158, 255, 0.3)'
                },
                {
                  offset: 1,
                  color: 'rgba(64, 158, 255, 0.1)'
                }
              ]
            }
          }
        }
      ]
    };

    myChart.setOption(option);

    // 响应式处理 - 使用防抖优化
    const debouncedResize = debounce(() => {
      if (myChart && !myChart.isDisposed()) {
        myChart.resize();
      }
    }, 200);

    chartResizeHandler.value = debouncedResize;
    window.addEventListener('resize', debouncedResize);
  } catch (error) {
    console.error('渲染图表失败:', error);
    const chartDom = document.getElementById('nodeCompletionChart');
    if (chartDom) {
      chartDom.innerHTML = `
        <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; color: #f56c6c;">
          <el-icon style="font-size: 48px; margin-bottom: 16px; opacity: 0.5;">
            <Warning />
          </el-icon>
          <div style="font-size: 14px; margin-bottom: 8px;">图表渲染失败</div>
          <div style="font-size: 12px; opacity: 0.7;">请刷新页面重试</div>
        </div>
      `;
    }
  }
};

/**
 * 批量保存所有编辑中的记录
 */
const handleBatchSave = async () => {
  const editingRecords = recordList.value.filter((record) => record.isEditing);

  if (editingRecords.length === 0) {
    ElMessage.warning('没有处于编辑状态的数据可以保存');
    return;
  }

  try {
    // 批量校验所有编辑中的记录
    const validationErrors: string[] = [];
    editingRecords.forEach((record, index) => {
      const validation = validateRecord(record);
      if (!validation.valid) {
        validationErrors.push(`第${index + 1}行：${validation.errors.join('、')}`);
      }
    });

    if (validationErrors.length > 0) {
      ElMessage.error(`批量保存失败：\n${validationErrors.join('\n')}`);
      return;
    }

    // 准备批量保存的数据 - 前端发送原始的百分比值（0-100），后端负责除以100
    const batchData: ProWeeklogRecordForm[] = editingRecords.map((record) => {
      // 封装记录数据，包含冗余字段更新所需的ID信息
      return {
        id: record.id,
        proId: record.proId,
        receiveId: record.receiveId,
        planId: record.planId,
        weeklogId: record.weeklogId,
        version: record.version,
        thisWeekCase: record.thisWeekCase,
        nodeCompleteRate: record.nodeCompleteRate,
        nextWeekPlan: record.nextWeekPlan,
        remark: record.remark,
        weekOrder: record.weekOrder
      };
    });

    // 调用批量保存接口
    await batchUpdateWeeklogRecord(batchData);
    ElMessage.success(`批量保存成功，共保存 ${editingRecords.length} 条记录`);

    // 批量保存后，将所有编辑态的记录退出编辑状态
    editingRecords.forEach((record) => {
      record.isEditing = false;
      record.originalData = null;
    });

    // 重新获取数据以确保数据同步
    getWeeklogData();
  } catch (error) {
    console.error('批量保存失败:', error);
    ElMessage.error('批量保存失败');
  }
};

/** 提交周总结审核 */
const handleSubmitWeeklog = () => {
  if (!weeklogData.value?.id) {
    ElMessage.error('周总结ID不能为空');
    return;
  }

  currentWeeklogForApproval.value = {
    id: weeklogData.value.id,
    proName: projectInfo.value.proName || '周总结'
  };
  approvalFlowVisible.value = true;
};

/**
 * 审核流程确认回调
 */
const handleApprovalConfirm = async () => {
  try {
    ElMessage.success('审核流程提交成功');
    approvalFlowVisible.value = false;
    currentWeeklogForApproval.value = null;
    // 刷新周总结数据
    await getWeeklogData();
  } catch (error) {
    console.error('审核流程提交失败:', error);
    ElMessage.error('审核流程提交失败');
  }
};

/**
 * 审核流程取消回调
 */
const handleApprovalCancel = () => {
  approvalFlowVisible.value = false;
  currentWeeklogForApproval.value = null;
};

onMounted(() => {
  getProjectDetail();
  initAndGetWeeklogData(true);
  // 初次渲染底部图表
  nextTick(() => {
    setTimeout(() => {
      renderProgressChartBottom();
      renderWorktimeChartBottom();
    }, 100);
  });
});

onUnmounted(() => {
  // 清理resize事件监听器
  if (chartResizeHandler.value) {
    window.removeEventListener('resize', chartResizeHandler.value);
    chartResizeHandler.value = null;
  }

  // 清理图表实例
  if (chartInstance.value) {
    chartInstance.value.dispose();
    chartInstance.value = null;
  }



  // 清理底部进度图表
  if (progressChartBottomResizeHandler.value) {
    window.removeEventListener('resize', progressChartBottomResizeHandler.value);
    progressChartBottomResizeHandler.value = null;
  }

  if (progressChartBottomInstance.value) {
    progressChartBottomInstance.value.dispose();
    progressChartBottomInstance.value = null;
  }

  // 清理工时统计图表
  if (worktimeChartBottomResizeHandler.value) {
    window.removeEventListener('resize', worktimeChartBottomResizeHandler.value);
    worktimeChartBottomResizeHandler.value = null;
  }

  if (worktimeChartBottomInstance.value) {
    worktimeChartBottomInstance.value.dispose();
    worktimeChartBottomInstance.value = null;
  }
});
</script>

<style lang="scss" scoped>
.app-container {
  padding: 20px;
}

/* 顶部简化进度条样式 */
/* 清理未使用的顶部进度条与侧边面板样式 */

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  background: linear-gradient(135deg, #f8faff 0%, #e8f4ff 100%);
  border-bottom: 1px solid #e1ecff;
  position: sticky;
  top: 0;
  z-index: 1;
}

.close-panel-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.8);
  border: 1px solid #e1ecff;
  transition: all 0.3s ease;
}

.close-panel-btn:hover {
  background: #fff;
  border-color: var(--el-color-primary);
  color: var(--el-color-primary);
  transform: scale(1.1);
}

.panel-content {
  padding: 20px;
  height: calc(100% - 81px);
  overflow-y: auto;
  overflow-x: hidden;
}

/* 新的统计布局样式 */
.statistics-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-bottom: 20px;
}

/* 通用模块样式 */
.progress-module,
.worktime-module {
  background: linear-gradient(135deg, #f8faff 0%, #f0f7ff 100%);
  border: 2px solid #e1ecff;
  border-radius: 16px;
  padding: 20px;
  box-shadow: 0 8px 24px rgba(64, 158, 255, 0.1);
  position: relative;
  overflow: hidden;
}

.progress-module::before,
.worktime-module::before {
  content: '';
  position: absolute;
  top: -50%;
  right: -20%;
  width: 120px;
  height: 120px;
  background: radial-gradient(circle, rgba(64, 158, 255, 0.03) 0%, transparent 70%);
  border-radius: 50%;
}

/* 节标题样式 */
.section-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 2px solid #f5f7fa;
  position: relative;
  z-index: 2;
}

.section-icon {
  font-size: 18px;
  color: var(--el-color-primary);
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

/* 模块内容布局 */
.module-content {
  display: flex;
  align-items: center;
  gap: 24px;
  position: relative;
  z-index: 2;
}

/* 图表容器 */
.chart-container {
  position: relative;
  flex-shrink: 0;
}

.progress-chart,
.worktime-chart {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}

/* 图表中心文字 */
.chart-center-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  pointer-events: none;
  z-index: 10;
}

.chart-center-text .percent-text {
  font-size: 20px;
  font-weight: 900;
  color: #2c7be5;
  line-height: 1;
  margin-bottom: 4px;
}

.chart-center-text .chart-label {
  font-size: 12px;
  color: #666;
  font-weight: 500;
}

/* 信息面板 */
.info-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 项目完成度模块 - 状态徽章 */
.status-badge {
  display: flex;
  justify-content: flex-start;
}

.status-badge .el-tag {
  font-size: 14px;
  padding: 8px 16px;
  border-radius: 20px;
  font-weight: 600;
}

/* 项目完成度模块 - 时间信息 */
.time-info {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.time-item {
  background: rgba(255, 255, 255, 0.8);
  padding: 12px 16px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  transition: all 0.3s ease;
}

.time-item:hover {
  background: #fff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.time-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #666;
  font-weight: 500;
  margin-bottom: 4px;
}

.time-value {
  font-size: 14px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

/* 工时统计模块 - 工时统计 */
.worktime-stats {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.worktime-item {
  background: rgba(255, 255, 255, 0.8);
  padding: 12px 16px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  transition: all 0.3s ease;
}

.worktime-item:hover {
  background: #fff;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.worktime-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
}

.worktime-icon.plan {
  background: #eef5ff;
  color: #5a8cff;
}

.worktime-icon.actual {
  background: #fff4eb;
  color: #ff9f43;
}

.worktime-details {
  flex: 1;
}

.worktime-label {
  font-size: 12px;
  color: #666;
  font-weight: 500;
  margin-bottom: 2px;
}

.worktime-value {
  font-size: 16px;
  font-weight: 700;
  color: var(--el-text-color-primary);
}

/* 工时统计模块 - 效率徽章 */
.efficiency-badge {
  display: flex;
  justify-content: flex-start;
}

.efficiency-badge .el-tag {
  font-size: 14px;
  padding: 8px 16px;
  border-radius: 20px;
  font-weight: 600;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
  background: #fff;
  min-height: 48px;
}

.card-header-actions .collapse-btn {
  width: 28px;
  height: 28px;
}

.collapse-btn .el-icon {
  transition: transform 0.2s ease;
}

.collapse-btn .el-icon.rotated {
  transform: rotate(180deg);
}

/* 统计区整体收起/展开动画 */
.stat-collapse-enter-active,
.stat-collapse-leave-active {
  transition: all 0.25s ease;
}

.stat-collapse-enter-from,
.stat-collapse-leave-to {
  opacity: 0;
  transform: translateY(-6px);
}

.card-header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.card-header-left .title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.card-header-left .el-button {
  transition: all 0.2s ease;
}

.card-header-left .el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.cycle-tag {
  margin-left: 8px;
  border-radius: 4px;
  font-weight: 600;
}



.refresh-button {
  width: 28px;
  height: 28px;
  background: #f5f7fa;
  border: 1px solid #dcdfe6;
  transition: all 0.2s;
}

.refresh-button:hover {
  border-color: #409eff;
  background: #ecf5ff;
  color: #409eff;
}

.week-info {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 8px;
  border: 1px solid #dee2e6;
}

.week-label {
  font-size: 14px;
  font-weight: 500;
  color: #495057;
  white-space: nowrap;
}

.weeklog-container {
  position: relative;
  margin-top: 20px;

  :deep(.el-table) {
    .el-table__cell {
      vertical-align: middle;
    }
  }
}

/* 周日志表格固定高度样式 */
.weeklog-table {
  :deep(.el-table__body-wrapper) {
    max-height: 600px;
    overflow-y: auto;
    overflow-x: auto;
  }

  :deep(.el-table__header-wrapper) {
    position: sticky;
    top: 0;
    z-index: 10;
    background: #fff;
  }

  :deep(.el-table__fixed-header-wrapper) {
    position: sticky;
    top: 0;
    z-index: 11;
    background: #fff;
  }

  /* 固定列样式优化 */
  :deep(.el-table__fixed-left) {
    box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
  }

  :deep(.el-table__fixed-right) {
    box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
  }

  /* 滚动条样式优化 */
  :deep(.el-table__body-wrapper)::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }

  :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
    background: #f5f7fa;
    border-radius: 4px;
  }

  :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
    background: #c0c4cc;
    border-radius: 4px;
  }

  :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
    background: #909399;
  }
}



/* 滑动提示样式 */
.scroll-tip-container {
  margin-top: 16px;
  display: flex;
  justify-content: space-between;
}

.scroll-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 12px;
  color: #909399;
  background-color: #f5f7fa;
  border: 1px solid #e4e7ed;
  padding: 6px 12px;
  border-radius: 4px;
  display: inline-flex;
}

.batch-save-right {
  display: flex;
  align-items: center;
}

.tip-icon {
  font-size: 14px;
  color: #909399;
}

.tip-text {
  font-size: 12px;
  color: #909399;
}

/* 批量保存按钮容器样式 */
.submit-button-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
}

.left-buttons {
  display: flex;
  gap: 12px;
}

.submit-button-container .el-button {
  min-width: 160px;
  height: 44px;
  font-size: 16px;
  font-weight: 600;
  transition: all 0.3s ease;
}

.submit-button-container .el-button--success {
  box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
}

.submit-button-container .el-button:hover {
  transform: translateY(-2px);
}

.submit-button-container .el-button--success:hover {
  box-shadow: 0 6px 16px rgba(103, 194, 58, 0.4);
}

/* 右下角悬浮批量保存按钮 */
.batch-save-float {
  position: sticky;
  bottom: 12px;
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}

.batch-save-btn {
  min-width: 112px;
  height: 32px;
  font-weight: 600;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(103, 194, 58, 0.25);
}

.text-overflow {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: top;
}

/* 周日志卡片样式 */
.weeklog-card {
  margin-bottom: 24px;
  padding-bottom: 8px;
  border-radius: 12px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

/* 编辑状态行背景色 */
:deep(.editing-row) {
  background-color: var(--el-color-primary-light-9);
}

:deep(.editing-row td) {
  background-color: var(--el-color-primary-light-9) !important;
}

/* 表格内的小尺寸组件调整 */
.weeklog-container :deep(.el-input__wrapper) {
  min-height: 28px;
}

.weeklog-container :deep(.el-input-number) {
  width: 100%;
}

.weeklog-container :deep(.el-input-number .el-input__wrapper) {
  min-height: 28px;
}

.weeklog-container :deep(.el-textarea__inner) {
  min-height: 60px;
  resize: vertical;
}

/* 表单验证错误样式 */
.weeklog-container :deep(.is-error .el-input__wrapper),
.weeklog-container :deep(.is-error .el-input-number .el-input__wrapper) {
  border-color: #f56c6c !important;
  box-shadow: 0 0 0 1px #f56c6c inset !important;
}

.weeklog-container :deep(.is-error .el-input__wrapper:hover),
.weeklog-container :deep(.is-error .el-input-number .el-input__wrapper:hover) {
  border-color: #f56c6c !important;
}



/* 回款节点名称样式（简洁 + 自动换行） */
.receive-name {
  font-weight: 600;
  font-size: 13px;
  display: block;
  white-space: normal;      /* 允许换行 */
  word-break: break-word;   /* 长单词或英文自动断行 */
  line-height: 1.5;
  text-align: center;
  background: none;         /* 去掉底色 */
  padding: 0;               /* 去掉内边距 */
  border-radius: 0;         /* 去掉圆角 */
}

/* 技术流程样式（去掉装饰 + 支持多行显示） */
.tech-flow-display {
  font-weight: 500;
  font-size: 13px;
  display: block;
  white-space: normal;      /* 允许换行 */
  word-break: break-word;   /* 自动断行 */
  line-height: 1.5;
  text-align: center;
  background: none;         /* 去掉背景色 */
  padding: 0;
  border: none;
  border-radius: 0;
  overflow: visible;        /* 显示全部内容 */
}








.progress-bar-container {
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  padding: 20px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.3);
}

.progress-bar-label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 500;
}

.progress-bar-label .label-left {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #606266;
}

.progress-bar-label .label-icon {
  font-size: 16px;
  color: #8fb9ff;
}

.progress-bar-value {
  color: var(--el-color-primary);
  font-weight: 600;
}

.custom-progress :deep(.el-progress-bar__outer) {
  background-color: rgba(245, 247, 250, 0.8);
  border-radius: 8px;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
}

.custom-progress :deep(.el-progress-bar__inner) {
  border-radius: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 响应式设计 */
@media (max-width: 1024px) and (min-width: 769px) {
  .statistics-layout {
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .module-content {
    gap: 20px;
  }
}

@media (max-width: 768px) {
  .statistics-layout {
    grid-template-columns: 1fr;
    gap: 16px;
  }

  .module-content {
    flex-direction: column;
    gap: 16px;
    text-align: center;
  }

  .progress-chart,
  .worktime-chart {
    width: 100px;
    height: 100px;
  }

  .chart-center-text .percent-text {
    font-size: 16px;
  }

  .time-info,
  .worktime-stats {
    width: 100%;
  }

  .app-container {
    padding: 8px;
  }

  .card-header {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }

  .card-header-left {
    flex-wrap: wrap;
    gap: 8px;
  }



  .week-info {
    padding: 6px 12px;
    justify-content: center;
  }

  .week-label {
    font-size: 13px;
  }



  .progress-bar-container {
    padding: 16px;
  }
}

/* 统计弹窗样式 */
.statistic-dialog :deep(.el-dialog__body) {
  padding: 20px;
}

.statistic-container {
  min-height: 400px;
}

.chart-card {
  margin-bottom: 20px;
  background: linear-gradient(135deg, #f8faff 0%, #f0f7ff 100%);
  border: 1px solid #e1ecff;
  box-shadow: 0 2px 12px rgba(64, 158, 255, 0.08);
}

.chart-header {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--el-color-primary);
  font-weight: 600;
}

.chart-icon {
  font-size: 18px;
}

#nodeCompletionChart {
  background: #fff;
  border-radius: 8px;
  border: 1px solid #e1ecff;
}

.record-header {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--el-text-color-primary);
  font-weight: 600;
}

.record-icon {
  font-size: 18px;
}

.dialog-footer {
  text-align: center;
  padding: 20px 0;
}

/* 右下角固定提交审核按钮样式 */
.fixed-submit-button {
  position: fixed;
  right: 30px;
  bottom: 30px;
  z-index: 999;
  transition: all 0.3s ease;
}

.submit-audit-btn {
  min-width: 180px;
  height: 56px;
  font-size: 16px;
  font-weight: 600;
  border-radius: 28px;
  box-shadow: 0 8px 24px rgba(64, 158, 255, 0.3);
  border: none;
  background: linear-gradient(135deg, #409EFF 0%, #66B1FF 100%);
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.submit-audit-btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 32px rgba(64, 158, 255, 0.4);
  background: linear-gradient(135deg, #337ecc 0%, #5aa1ff 100%);
}

.submit-audit-btn:active {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(64, 158, 255, 0.35);
}

.submit-audit-btn .el-icon {
  font-size: 18px;
}

.submit-audit-btn span {
  font-size: 16px;
  font-weight: 600;
}

/* 响应式适配 */
@media (max-width: 768px) {
  .fixed-submit-button {
    right: 16px;
    bottom: 16px;
  }

  .submit-audit-btn {
    min-width: 140px;
    height: 48px;
    font-size: 14px;
    border-radius: 24px;
  }

  .submit-audit-btn .el-icon {
    font-size: 16px;
  }

  .submit-audit-btn span {
    font-size: 14px;
  }
}

/* 当页面滚动时的动画效果 */
@keyframes buttonBounce {

  0%,
  20%,
  50%,
  80%,
  100% {
    transform: translateY(0);
  }

  40% {
    transform: translateY(-5px);
  }

  60% {
    transform: translateY(-3px);
  }
}

.fixed-submit-button:hover .submit-audit-btn {
  animation: buttonBounce 0.6s ease;
}
</style>
